// Units (单元) 示例
// 演示 Pascal 中单元的各种用法
program p_36_units;

{$mode objfpc}{$H+}
// {$mode objfpc} 启用 Object Pascal 模式
// {$H+} 启用长字符串支持（AnsiString）

// 引入单元文件
uses
  SysUtils,     // 系统工具单元
  Classes,      // 类单元
  Math;         // 数学单元

// 定义一个简单的数学工具类
type
  TMathHelper = class
  public
    class function Add(a, b: Double): Double;
    class function Subtract(a, b: Double): Double;
    class function Multiply(a, b: Double): Double;
    class function Divide(a, b: Double): Double;
  end;

// TMathHelper类的实现
class function TMathHelper.Add(a, b: Double): Double;
begin
  Result := a + b;
  WriteLn('  计算 ', a:0:2, ' + ', b:0:2, ' = ', Result:0:2);
end;

class function TMathHelper.Subtract(a, b: Double): Double;
begin
  Result := a - b;
  WriteLn('  计算 ', a:0:2, ' - ', b:0:2, ' = ', Result:0:2);
end;

class function TMathHelper.Multiply(a, b: Double): Double;
begin
  Result := a * b;
  WriteLn('  计算 ', a:0:2, ' * ', b:0:2, ' = ', Result:0:2);
end;

class function TMathHelper.Divide(a, b: Double): Double;
begin
  if b <> 0 then
  begin
    Result := a / b;
    WriteLn('  计算 ', a:0:2, ' / ', b:0:2, ' = ', Result:0:2);
  end
  else
  begin
    WriteLn('  错误：除数不能为零');
    Result := 0;
  end;
end;

// 定义一个学生记录
type
  TStudent = record
    Name: String;
    Age: Integer;
    Score: Double;
  end;

// 定义一个学生管理类
type
  TStudentManager = class
  private
    FStudents: array of TStudent;
    FCount: Integer;
  public
    constructor Create;
    destructor Destroy; override;
    procedure AddStudent(const AName: String; AAge: Integer; AScore: Double);
    function GetAverageScore: Double;
    procedure DisplayStudents;
    property Count: Integer read FCount;
  end;

// TStudentManager类的实现
constructor TStudentManager.Create;
begin
  inherited Create;
  FCount := 0;
  SetLength(FStudents, 10);  // 初始容量为10
  WriteLn('  创建学生管理器');
end;

destructor TStudentManager.Destroy;
begin
  WriteLn('  销毁学生管理器');
  inherited Destroy;
end;

procedure TStudentManager.AddStudent(const AName: String; AAge: Integer; AScore: Double);
begin
  if FCount >= Length(FStudents) then
    SetLength(FStudents, Length(FStudents) + 10);  // 扩容
  
  FStudents[FCount].Name := AName;
  FStudents[FCount].Age := AAge;
  FStudents[FCount].Score := AScore;
  Inc(FCount);
  
  WriteLn('  添加学生: ', AName, '，年龄: ', AAge, '，分数: ', AScore:0:1);
end;

function TStudentManager.GetAverageScore: Double;
var
  i: Integer;
  Total: Double;
begin
  if FCount = 0 then
  begin
    Result := 0;
    Exit;
  end;
  
  Total := 0;
  for i := 0 to FCount - 1 do
    Total := Total + FStudents[i].Score;
  
  Result := Total / FCount;
end;

procedure TStudentManager.DisplayStudents;
var
  i: Integer;
begin
  WriteLn('  学生列表:');
  for i := 0 to FCount - 1 do
    WriteLn('    ', i + 1, '. ', FStudents[i].Name, '，年龄: ', FStudents[i].Age, '，分数: ', FStudents[i].Score:0:1);
end;

// 程序主入口
begin
  WriteLn('=== Pascal 单元示例 ===');
  WriteLn;
  
  // 1. 使用系统单元中的函数
  WriteLn('1. 使用系统单元中的函数:');
  var currentDate: TDateTime := Now;
  WriteLn('  当前日期时间: ', DateTimeToStr(currentDate));
  WriteLn('  年份: ', YearOf(currentDate));
  WriteLn('  月份: ', MonthOf(currentDate));
  WriteLn('  日期: ', DayOf(currentDate));
  
  WriteLn;
  var randomValue: Double := Random;
  WriteLn('  随机数: ', randomValue:0:6);
  
  WriteLn;
  
  // 2. 使用自定义类进行数学计算
  WriteLn('2. 使用自定义类进行数学计算:');
  var resultAdd: Double := TMathHelper.Add(15.5, 24.3);
  var resultSub: Double := TMathHelper.Subtract(50.0, 18.7);
  var resultMul: Double := TMathHelper.Multiply(12.5, 4.0);
  var resultDiv: Double := TMathHelper.Divide(100.0, 25.0);
  
  WriteLn;
  
  // 3. 使用数学单元中的函数
  WriteLn('3. 使用数学单元中的函数:');
  var angle: Double := 45.0;
  var rad: Double := DegToRad(angle);
  WriteLn('  ', angle:0:1, '度 = ', rad:0:6, '弧度');
  WriteLn('  sin(', angle:0:1, '°) = ', Sin(rad):0:6);
  WriteLn('  cos(', angle:0:1, '°) = ', Cos(rad):0:6);
  WriteLn('  tan(', angle:0:1, '°) = ', Tan(rad):0:6);
  
  WriteLn;
  var value: Double := 16.0;
  WriteLn('  √', value:0:1, ' = ', Sqrt(value):0:6);
  WriteLn('  ln(', value:0:1, ') = ', Ln(value):0:6);
  WriteLn('  log10(', value:0:1, ') = ', Log10(value):0:6);
  
  WriteLn;
  
  // 4. 使用学生管理器
  WriteLn('4. 使用学生管理器:');
  var studentManager: TStudentManager := TStudentManager.Create;
  try
    studentManager.AddStudent('张三', 20, 85.5);
    studentManager.AddStudent('李四', 19, 92.0);
    studentManager.AddStudent('王五', 21, 78.5);
    studentManager.AddStudent('赵六', 20, 88.0);
    
    WriteLn;
    studentManager.DisplayStudents;
    
    WriteLn;
    WriteLn('  平均分: ', studentManager.GetAverageScore:0:2);
    WriteLn('  学生总数: ', studentManager.Count);
  finally
    studentManager.Free;
  end;
  
  WriteLn;
  
  // 5. 字符串处理示例
  WriteLn('5. 字符串处理示例:');
  var text: String := '  Hello, Pascal World!  ';
  WriteLn('  原始文本: "', text, '"');
  WriteLn('  长度: ', Length(text));
  WriteLn('  去除空格后: "', Trim(text), '"');
  WriteLn('  转大写: "', UpperCase(text), '"');
  WriteLn('  转小写: "', LowerCase(text), '"');
  
  WriteLn;
  var position: Integer := Pos('Pascal', text);
  if position > 0 then
    WriteLn('  "Pascal" 在位置 ', position, ' 处')
  else
    WriteLn('  未找到 "Pascal"');
  
  WriteLn;
  
  // 6. 文件操作示例
  WriteLn('6. 文件操作示例:');
  var fileName: String := 'test.txt';
  var fileVar: Text;
  
  // 创建并写入文件
  Assign(fileVar, fileName);
  Rewrite(fileVar);
  WriteLn(fileVar, '这是Pascal单元示例文件');
  WriteLn(fileVar, '创建时间: ', DateTimeToStr(Now));
  Close(fileVar);
  WriteLn('  已创建文件: ', fileName);
  
  // 读取文件内容
  Assign(fileVar, fileName);
  Reset(fileVar);
  WriteLn('  文件内容:');
  while not Eof(fileVar) do
  begin
    var line: String;
    ReadLn(fileVar, line);
    WriteLn('    ', line);
  end;
  Close(fileVar);
  
  // 删除测试文件
  if FileExists(fileName) then
  begin
    Erase(fileVar);
    WriteLn('  已删除文件: ', fileName);
  end;
  
  WriteLn;
  WriteLn('演示了 Pascal 中单元的各种用法');
  
  // 等待用户按键，防止程序窗口立即关闭
  ReadLn;
end.